﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Foundation.Core
{
    public static class ServiceCollectionSelectCollectionExtensions
    {
        public static IServiceCollection AddSelectCollectionService(this IServiceCollection services, Action<SelectCollectionServiceOptionsBuilder> configure)
        {
            services.TryAddTransient<ServiceMethodSelectCollectionCreatorFactory>();
            services.TryAddTransient<ISelectCollectionService, SelectCollectionService>();
            services.TryAddTransient<SelectItemLoadMethodConverterFactory>();
            services.TryAddTransient<CurrentUserSelectParameterValueProvider>();

            var registrar = SelectFilterRegistrar.Default;
            var store = SelectCollectionStore.Default;
            var parameterTypeValueProviderRegistrar = SelectCollectionParameterTypeValueProviderRegistrar.Default;

            services.TryAddSingleton(registrar);
            services.TryAddSingleton(store);
            services.TryAddSingleton(parameterTypeValueProviderRegistrar);

            var builder = new SelectCollectionServiceOptionsBuilder(store, registrar, parameterTypeValueProviderRegistrar);

            if (configure != null)
            {
                configure.Invoke(builder);
            }

            if (builder.IsEnabledListingLoadAssembly && !builder.AssemblyConfiguration.IsNullOrEmpty())
            {
                var assemblies = AppDomain.CurrentDomain.GetAssemblies();

                foreach (var assembly in assemblies)
                {
                    foreach (var c in builder.AssemblyConfiguration)
                    {
                        c.Invoke(builder, assembly);
                    }
                }

                AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
                {
                    foreach (var c in builder.AssemblyConfiguration)
                    {
                        c.Invoke(builder, args.LoadedAssembly);
                    }
                };
            }

            return services;
        }
    }
}
